import { Inject, Provide } from '@midwayjs/decorator';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Equal, Repository, In } from 'typeorm';
import { UserInfoEntity } from '../entity/info';
import { OrderInfoEntity } from '../../order/entity/info';
import { v1 as uuid } from 'uuid';
import { UserSmsService } from './sms';
import * as md5 from 'md5';
import { PluginService } from '../../plugin/service/info';
import { UserWxService } from './wx';
import moment = require('moment');
import * as _ from 'lodash';
import axios from 'axios';
import { DictInfoService } from '../../dict/service/info';
/**
 * 用户信息
 */
@Provide()
export class UserInfoService extends BaseService {
  @InjectEntityModel(UserInfoEntity)
  userInfoEntity: Repository<UserInfoEntity>;

  @InjectEntityModel(OrderInfoEntity)
  orderInfoEntity: Repository<OrderInfoEntity>;


  @Inject()
  pluginService: PluginService;

  @Inject()
  userSmsService: UserSmsService;

  @Inject()
  dictInfoService: DictInfoService;

  @Inject()
  userWxService: UserWxService;

  /**
   * 绑定小程序手机号
   * @param userId
   * @param code
   * @param encryptedData
   * @param iv
   */
  async miniPhone(userId: number, code: any, encryptedData: any, iv: any) {
    const phone = await this.userWxService.miniPhone(code, encryptedData, iv);
    await this.userInfoEntity.update({ id: Equal(userId) }, { phone });
    return phone;
  }

  /**
   * 推送消息
   * @param ids
   * @param title
   * @param content
   * @param payload
   * @returns
   */
  async sendPushMessage(ids, title, content, payload) {
    console.log(ids, title, content, payload)
    if (_.isEmpty(ids)) {
      return
    }
    let list = await this.userInfoEntity.findBy({ id: In(ids), push: 1 })
    if (_.isEmpty(list)) {
      return
    }
    await axios.post(
      'https://fc-mp-602801f5-1a23-4f15-b60a-9d30f5efa098.next.bspapp.com/push',
      {
        push_clientid: list.map(e => {
          return e.clientId;
        }),
        title,
        content,
        payload,
        request_id: uuid()
      }
    );
  }
  /**
   * 推送小程序消息
   * @param userId
   * @param title
   * @param content
   * @param payload
   * @returns
   */
  async sendMiMessage(userId, template_id, type, data, id) {
    const token = await this.userWxService.getWxToken();
    let url = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' + token
    let touser = await this.userWxService.getOpenid(userId)
    let page = await this.dictInfoService.getValues(type, 'push') + '?id=' + id
    let from = JSON.stringify({ template_id, touser, page, data })
    await axios.post(
      url,
      from
    );
  }
  /**
   * 定时刷新可观看广告数量
   * @param id
   * @returns
   */
  async setAdNumber() {
    let list = await this.userInfoEntity.findBy({ adNumber: In([0, 1, 2]), adViewing: 0 })
    let ids = list.map(item => {
      return item.id
    })
    let start = moment()
    await this.userInfoEntity.update({ id: In(ids) }, { adNumber: 3 });
    let end = moment()
    var duration = moment.duration(end.diff(start));
    return `处理成功,共修改${ids.length}人,耗时${duration.as('seconds')}s`
  }

  /**
    * 将所有人设置为不可观看广告
    * @param id
    * @returns
    */
  async notAdNumber() {
    let list = await this.userInfoEntity.findBy({ adNumber: In([0, 1, 2]), adViewing: 0 })
    let ids = list.map(item => {
      return item.id
    })
    let start = moment()
    await this.userInfoEntity.update({ id: In(ids) }, { adNumber: 0, adViewing: 1 });
    let end = moment()
    var duration = moment.duration(end.diff(start));
    return `处理成功,共修改${ids.length}人,耗时${duration.as('seconds')}s`
  }
  /**
   * 获取用户信息
   * @param id
   * @returns
   */
  async person(id) {
    const info = await this.userInfoEntity.findOneBy({ id: Equal(id) });
    // 手机号脱敏
    if (info && info.phone) {
      info.phone = info.phone.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2');
    }
    return info;
  }

  /**
   * 注销
   * @param userId
   */
  async logoff(userId: number) {
    let isOrder = await this.orderInfoEntity.findBy({ status: In([0, 1, 2, 5]), userId })
    if (isOrder) {
      throw new CoolCommException('检测到有未完成的商城订单,请处理后进行注销');
    }
    await this.userInfoEntity.update(
      { id: userId },
      {
        status: 2,
        phone: null,
        unionid: null,
        nickName: `已注销-00${userId}`,
        avatarUrl: null,
      }
    );
  }

  /**
   * 更新用户信息
   * @param id
   * @param param
   * @returns
   */
  async updatePerson(id, param) {
    const info = await this.person(id);
    if (!info) throw new CoolCommException('用户不存在');
    try {
      // 修改了头像要重新处理
      if (param.avatarUrl && info.avatarUrl != param.avatarUrl) {
        const file = await this.pluginService.getInstance('upload');
        param.avatarUrl = await file.downAndUpload(
          param.avatarUrl,
          uuid() + '.png'
        );
      }
    } catch (err) { }
    try {
      return await this.userInfoEntity.update({ id }, param);
    } catch (err) {
      throw new CoolCommException('更新失败，参数错误或者手机号已存在');
    }
  }

  /**
   * 更新密码
   * @param userId
   * @param password
   * @param 验证码
   */
  async updatePassword(userId, password, code) {
    const user = await this.userInfoEntity.findOneBy({ id: userId });
    const check = await this.userSmsService.checkCode(user.phone, code);
    if (!check) {
      throw new CoolCommException('验证码错误');
    }
    await this.userInfoEntity.update(user.id, { password: md5(password) });
  }

  /**
   * 绑定手机号
   * @param userId
   * @param phone
   * @param code
   */
  async bindPhone(userId, phone, code) {
    const check = await this.userSmsService.checkCode(phone, code);
    if (!check) {
      throw new CoolCommException('验证码错误');
    }
    await this.userInfoEntity.update({ id: userId }, { phone });
  }
}
